//------------------------------------------------------------------------------

#include "action.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "util.h"

//------------------------------------------------------------------------------
#define BUFFER_SIZE		1024
//------------------------------------------------------------------------------
typedef struct _SAction {
	ETypeAction type;
	int start;
	int end;
	struct _SAction *next;
} SAction;
//------------------------------------------------------------------------------
static SAction *firstAction = 0;
static SAction *lastAction = 0;
//------------------------------------------------------------------------------
int static compare(SAction *s1, SAction *s2) {
	if (s1->type == s2->type) {
		if (s1->type == etaDelete) {
			return s2->start - s1->start;
		}
		return s1->start - s2->start;
	}

	if (s1->type == etaDelete) {
		return -1;
	}

	return 1;
}
//------------------------------------------------------------------------------
void static insert(SAction *action) {
	SAction *p = firstAction;
	SAction *prev = 0;

	while (p != 0) {
		if (compare(action, p) < 0) {
			if (p == firstAction) {
				action->next = firstAction;
				firstAction = action;
			} else {
				action->next = p;
				prev->next = action;
			}

			lastAction = action;
			return;
		}
		prev = p;
		p = p->next;
	}

	if (p == 0) {
		prev->next = action;
		lastAction = action;
	}
}
//------------------------------------------------------------------------------
void addAction(ETypeAction type, int start) {
	if (firstAction == 0) {
		firstAction = (SAction *) calloc(1, sizeof(SAction));
		lastAction = firstAction;
		lastAction->type = type;
		lastAction->start = start;
		lastAction->end = start;
	} else {
		if (lastAction->type == type && lastAction->end == start - 1) {
			lastAction->end = start;
		} else {
			SAction *newAction = (SAction *) calloc(1, sizeof(SAction));
			newAction->type = type;
			newAction->start = start;
			newAction->end = start;

			insert(newAction);
		}
	}
}
//------------------------------------------------------------------------------
void computeActions(char **lignes, char **result) {
	SAction *p = firstAction;
	int resultSize = 0;
	int nbLigne = 0;

	while (p != 0) {
		int nb = p->end - p->start + 1;
		char buffer[BUFFER_SIZE];

		if (nbLigne > 0) {
			resultSize = reallocExCpy(result, resultSize, "\n");
		}

		sprintf(buffer, "%c %d,%d", (char) p->type, p->start, nb);
		nbLigne++;
		resultSize = reallocExCpy(result, resultSize, buffer);
		if (p->type == etaAdd) {
			int i;

			for (i = p->start; i <= p->end; i++) {
				resultSize = reallocExCpy(result, resultSize, "\n");
				resultSize = reallocExCpy(result, resultSize, "> ");
				resultSize = reallocExCpy(result, resultSize, lignes[i]);
				nbLigne++;
			}

		}
		p = p->next;
	}
}
//------------------------------------------------------------------------------
void freeActions(void) {
	SAction *p = firstAction;
	while (p != 0) {
		SAction *next = p->next;
		free(p);
		p = next;
	}

	firstAction = 0;
	lastAction = 0;
}
//------------------------------------------------------------------------------
